package com.designpattern.test;

import com.designpattern.structure.adapter.Adapter;
import com.designpattern.structure.bridge.Biz1;
import com.designpattern.structure.bridge.Biz2;
import com.designpattern.structure.bridge.MainBiz;
import com.designpattern.structure.decorator.BizImpl;
import com.designpattern.structure.decorator.BizInterface;
import com.designpattern.structure.decorator.ConcreteDecorator;
import com.designpattern.structure.decorator.ConcreteDecorator2;
import com.designpattern.structure.facade.MainBiz_facade;
import com.designpattern.structure.facade.SlaveBiz1;
import com.designpattern.structure.facade.SlaveBiz2;
import com.designpattern.structure.flyweight.FlyweightFactory;
import com.designpattern.structure.flyweight.FlyweightImpl;
import com.designpattern.structure.proxy.active.BizInvocationHandler;
import com.designpattern.structure.proxy.statically.ProxiedClz;
import com.designpattern.structure.proxy.statically.ProxyBiz;
import com.designpattern.structure.proxy.statically.ProxyClz;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;

import java.lang.reflect.Proxy;

@Slf4j
public class StructureTester {

    @Test
    public void adapterTest(){
        log.info(Adapter.biz1());
        log.info(Adapter.biz2());
    }

    @Test
    public void bridgeTest(){
        MainBiz mainBiz1 = new MainBiz(new Biz1());
        MainBiz mainBiz2 = new MainBiz(new Biz2());

        mainBiz1.mainBiz();
        mainBiz2.mainBiz();
    }

    @Test
    public void decoratorTest(){
        BizInterface bizImpl = new BizImpl();
        ConcreteDecorator concreteDecorator = new ConcreteDecorator(bizImpl);
        ConcreteDecorator2 concreteDecorator2 = new ConcreteDecorator2(concreteDecorator);

        concreteDecorator2.biz();
    }

    @Test
    public void facadeTest(){
        MainBiz_facade mainBiz = new MainBiz_facade(new SlaveBiz1(),new SlaveBiz2());
        mainBiz.biz1();
        mainBiz.biz2();
    }

    @Test
    public void flyweightTest(){
        FlyweightFactory flyweightFactory = new FlyweightFactory();
        FlyweightImpl flyweight = flyweightFactory.getFlyweight("test");
        flyweight.biz();
    }

    @Test
    public void staticProxyTest(){
        ProxyClz proxyClz = new ProxyClz(new ProxiedClz());
        proxyClz.biz();
    }

    @Test
    public void activeProxyTest(){
        ProxyBiz proxiedClz = new ProxiedClz();

        BizInvocationHandler bizInvocationHandler = new BizInvocationHandler(proxiedClz);

        ProxyBiz proxyClz = (ProxyBiz) Proxy.newProxyInstance(ProxyBiz.class.getClassLoader(),new Class<?>[]{ProxyBiz.class},bizInvocationHandler);

        proxyClz.biz();
    }
}
